package blink.view.experiment;

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.border.LineBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import blink.guimodel.TaskXpListModel;
import blink.guimodel.xpListModel;
import blink.model.Experiment;
import blink.model.ExperimentRenderer;
import blink.model.Task;
import blink.view.main_panel.MainFrame;
import blink.view.slide_show.SlideShow;

public class ExperimentPanel extends JPanel {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private JLabel lblTachesDeLexprience;
	private JLabel lblNombreDessaisDe;
	private JList jListTasksExp;
	private JList jListTryExp;
	private JButton btnNewButton;
	public JButton btnAddTaskToExp;
	private JButton btnRemTaskFromExp;
	private JLabel lblNewLabel;
	private JLabel lblFichier;
	private JTextField textFieldLastname;
	private JTextField nomFichier;
	private JLabel lblPrnom;
	private JLabel lblAge;
	private JTextField textFieldName;
	private JTextField textFieldAge;
	private JLabel lblComment;
	private JTextArea textArea;
	private JButton btnAddTry;
	private JButton btnRemTry;

	private FormListener formListener = new FormListener();
	private MainFrame mainFrame;
	private TaskXpListModel<Task> taskXpModel;
	private xpListModel nbTryXpModel;
	private Experiment experiment;

	/**
	 * Create the panel.
	 */
	public ExperimentPanel(Experiment exp, MainFrame mainFrame) {

		this.mainFrame = mainFrame;
		this.experiment = exp;

		taskXpModel = new TaskXpListModel();
		taskXpModel.setModel(this.experiment);
		nbTryXpModel = new xpListModel();
		nbTryXpModel.setModel(this.experiment);

		GridBagLayout gridBagLayout = new GridBagLayout();
		gridBagLayout.columnWeights = new double[] { 0.2, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0 };
		gridBagLayout.rowWeights = new double[] { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 };
		setLayout(gridBagLayout);

		textFieldLastname = new JTextField();
		GridBagConstraints gbc_textField = new GridBagConstraints();
		gbc_textField.insets = new Insets(0, 0, 5, 20);
		gbc_textField.fill = GridBagConstraints.HORIZONTAL;
		gbc_textField.gridx = 8;
		gbc_textField.gridy = 0;
		add(textFieldLastname, gbc_textField);
		textFieldLastname.setColumns(10);
		textFieldLastname.addFocusListener(formListener);

		btnAddTry = new JButton(Messages.getString("ExperimentPanel.0")); //$NON-NLS-1$
		GridBagConstraints gbc_button = new GridBagConstraints();
		gbc_button.fill = GridBagConstraints.VERTICAL;
		gbc_button.gridheight = 4;
		gbc_button.insets = new Insets(0, 0, 5, 5);
		gbc_button.gridx = 6;
		gbc_button.gridy = 1;
		add(btnAddTry, gbc_button);
		btnAddTry.addActionListener(formListener);

		lblPrnom = new JLabel(Messages.getString("ExperimentPanel.1")); //$NON-NLS-1$
		GridBagConstraints gbc_lblPrnom = new GridBagConstraints();
		gbc_lblPrnom.anchor = GridBagConstraints.EAST;
		gbc_lblPrnom.insets = new Insets(0, 0, 5, 5);
		gbc_lblPrnom.gridx = 7;
		gbc_lblPrnom.gridy = 1;
		add(lblPrnom, gbc_lblPrnom);

		textFieldName = new JTextField();
		GridBagConstraints gbc_textField_1 = new GridBagConstraints();
		gbc_textField_1.insets = new Insets(0, 0, 5, 20);
		gbc_textField_1.fill = GridBagConstraints.HORIZONTAL;
		gbc_textField_1.gridx = 8;
		gbc_textField_1.gridy = 1;
		add(textFieldName, gbc_textField_1);
		textFieldName.setColumns(10);
		textFieldName.addFocusListener(formListener);

		lblAge = new JLabel(Messages.getString("ExperimentPanel.2")); //$NON-NLS-1$
		GridBagConstraints gbc_lblAge = new GridBagConstraints();
		gbc_lblAge.anchor = GridBagConstraints.EAST;
		gbc_lblAge.insets = new Insets(0, 0, 5, 5);
		gbc_lblAge.gridx = 7;
		gbc_lblAge.gridy = 2;
		add(lblAge, gbc_lblAge);

		textFieldAge = new JTextField();
		GridBagConstraints gbc_textField_2 = new GridBagConstraints();
		gbc_textField_2.insets = new Insets(0, 0, 5, 20);
		gbc_textField_2.fill = GridBagConstraints.HORIZONTAL;
		gbc_textField_2.gridx = 8;
		gbc_textField_2.gridy = 2;
		add(textFieldAge, gbc_textField_2);
		textFieldAge.setColumns(10);
		textFieldAge.addFocusListener(formListener);

		lblComment = new JLabel(Messages.getString("ExperimentPanel.3")); //$NON-NLS-1$
		GridBagConstraints gbc_lblComment = new GridBagConstraints();
		gbc_lblComment.anchor = GridBagConstraints.NORTHEAST;
		gbc_lblComment.insets = new Insets(0, 0, 5, 5);
		gbc_lblComment.gridx = 7;
		gbc_lblComment.gridy = 3;
		add(lblComment, gbc_lblComment);

		textArea = new JTextArea();
		GridBagConstraints gbc_textArea = new GridBagConstraints();
		gbc_textArea.gridheight = 5;
		gbc_textArea.insets = new Insets(0, 0, 5, 20);
		gbc_textArea.fill = GridBagConstraints.BOTH;
		gbc_textArea.gridx = 8;
		gbc_textArea.gridy = 3;
		add(textArea, gbc_textArea);
		textArea.addFocusListener(formListener);
		
		lblFichier = new JLabel(Messages.getString("ExperimentPanel.4")); //$NON-NLS-1$
		GridBagConstraints gbc_lblFichier = new GridBagConstraints();
		gbc_lblFichier.anchor = GridBagConstraints.EAST;
		gbc_lblFichier.insets = new Insets(0, 0, 5, 5);
		gbc_lblFichier.gridx = 7;
		gbc_lblFichier.gridy = 8;
		add(lblFichier, gbc_lblFichier);

		nomFichier=new JTextField();
		GridBagConstraints gbc_nomFichier = new GridBagConstraints();
		gbc_nomFichier.insets = new Insets(0, 0, 5, 20);
		gbc_nomFichier.fill = GridBagConstraints.HORIZONTAL;
		gbc_nomFichier.gridx = 8;
		gbc_nomFichier.gridy = 8;
		nomFichier.setColumns(10);
		add(nomFichier, gbc_nomFichier);
		nomFichier.addFocusListener(formListener);


		btnRemTaskFromExp = new JButton(Messages.getString("ExperimentPanel.5")); //$NON-NLS-1$
		GridBagConstraints gbc_btnNewButton_2 = new GridBagConstraints();
		gbc_btnNewButton_2.gridheight = 5;
		gbc_btnNewButton_2.fill = GridBagConstraints.VERTICAL;
		gbc_btnNewButton_2.insets = new Insets(0, 0, 0, 5);
		gbc_btnNewButton_2.gridx = 0;
		gbc_btnNewButton_2.gridy = 5;
		add(btnRemTaskFromExp, gbc_btnNewButton_2);
		btnRemTaskFromExp.addActionListener(formListener);

		btnAddTaskToExp = new JButton(Messages.getString("ExperimentPanel.6")); //$NON-NLS-1$
		GridBagConstraints gbc_btnNewButton_1 = new GridBagConstraints();
		gbc_btnNewButton_1.fill = GridBagConstraints.VERTICAL;
		gbc_btnNewButton_1.gridheight = 5;
		gbc_btnNewButton_1.insets = new Insets(0, 0, 5, 5);
		gbc_btnNewButton_1.gridx = 0;
		gbc_btnNewButton_1.gridy = 0;
		add(btnAddTaskToExp, gbc_btnNewButton_1);
		// ////////////////////////////////////////////////////////////////////////////
		btnAddTaskToExp.addActionListener(formListener);

		btnRemTry = new JButton(Messages.getString("ExperimentPanel.7")); //$NON-NLS-1$
		GridBagConstraints gbc_button_1 = new GridBagConstraints();
		gbc_button_1.fill = GridBagConstraints.VERTICAL;
		gbc_button_1.gridheight = 4;
		gbc_button_1.insets = new Insets(0, 0, 5, 5);
		gbc_button_1.gridx = 6;
		gbc_button_1.gridy = 5;
		add(btnRemTry, gbc_button_1);
		btnRemTry.addActionListener(formListener);

		btnNewButton = new JButton(Messages.getString("ExperimentPanel.8")); //$NON-NLS-1$
		GridBagConstraints gbc_btnNewButton = new GridBagConstraints();
		gbc_btnNewButton.insets = new Insets(10, 5, 0, 10);
		gbc_btnNewButton.gridx = 8;
		gbc_btnNewButton.gridy = 9;
		add(btnNewButton, gbc_btnNewButton);
		btnNewButton.addActionListener(formListener);

		jListTasksExp = new JList<String>();
		jListTasksExp.setBorder(new LineBorder(Color.LIGHT_GRAY, 1, true));
		jListTasksExp.setVisibleRowCount(15);
		jListTasksExp.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		GridBagConstraints gbc_list = new GridBagConstraints();
		gbc_list.gridheight = 8;
		gbc_list.gridwidth = 2;
		gbc_list.fill = GridBagConstraints.BOTH;
		gbc_list.insets = new Insets(0, 5, 5, 5);
		gbc_list.gridx = 1;
		gbc_list.gridy = 1;
		add(jListTasksExp, gbc_list);
		jListTasksExp.setModel(taskXpModel);
		jListTasksExp.addListSelectionListener(alsl);

		jListTryExp = new JList();
		jListTryExp.setBorder(new LineBorder(Color.LIGHT_GRAY, 1, true));
		jListTryExp.setVisibleRowCount(15);
		jListTryExp.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		GridBagConstraints gbc_list_1 = new GridBagConstraints();
		gbc_list_1.gridheight = 8;
		gbc_list_1.insets = new Insets(0, 5, 5, 5);
		gbc_list_1.gridwidth = 2;
		gbc_list_1.fill = GridBagConstraints.BOTH;
		gbc_list_1.gridx = 4;
		gbc_list_1.gridy = 1;
		add(jListTryExp, gbc_list_1);
		jListTryExp.setModel(nbTryXpModel);
		jListTryExp.addListSelectionListener(alsl);

		lblTachesDeLexprience = new JLabel(Messages.getString("ExperimentPanel.9")); //$NON-NLS-1$
		lblTachesDeLexprience.setFont(new Font(Messages.getString("ExperimentPanel.10"), Font.BOLD, 12)); //$NON-NLS-1$
		GridBagConstraints gbc_lblTachesDeLexprience = new GridBagConstraints();
		gbc_lblTachesDeLexprience.insets = new Insets(0, 0, 5, 5);
		gbc_lblTachesDeLexprience.gridwidth = 2;
		gbc_lblTachesDeLexprience.gridx = 1;
		gbc_lblTachesDeLexprience.gridy = 0;
		add(lblTachesDeLexprience, gbc_lblTachesDeLexprience);

		lblNombreDessaisDe = new JLabel(Messages.getString("ExperimentPanel.11")); //$NON-NLS-1$
		lblNombreDessaisDe.setFont(new Font(Messages.getString("ExperimentPanel.12"), Font.BOLD, 12)); //$NON-NLS-1$
		GridBagConstraints gbc_lblNombreDessaisDe = new GridBagConstraints();
		gbc_lblNombreDessaisDe.insets = new Insets(0, 0, 5, 5);
		gbc_lblNombreDessaisDe.gridwidth = 2;
		gbc_lblNombreDessaisDe.gridx = 4;
		gbc_lblNombreDessaisDe.gridy = 0;
		add(lblNombreDessaisDe, gbc_lblNombreDessaisDe);

		lblNewLabel = new JLabel(Messages.getString("ExperimentPanel.13")); //$NON-NLS-1$
		GridBagConstraints gbc_lblNewLabel = new GridBagConstraints();
		gbc_lblNewLabel.anchor = GridBagConstraints.EAST;
		gbc_lblNewLabel.insets = new Insets(0, 0, 5, 5);
		gbc_lblNewLabel.gridx = 7;
		gbc_lblNewLabel.gridy = 0;
		add(lblNewLabel, gbc_lblNewLabel);

	}

	ListSelectionListener alsl = new ListSelectionListener() {
		@Override
		public void valueChanged(ListSelectionEvent lse) {
			if (lse.getSource() == jListTasksExp && jListTasksExp.getSelectedIndex() != -1)
				jListTryExp.setSelectedIndex(jListTasksExp.getSelectedIndex());
			else if (lse.getSource() == jListTryExp && jListTryExp.getSelectedIndex() != -1)
				jListTasksExp.setSelectedIndex(jListTryExp.getSelectedIndex());
		}
	};

	private class FormListener implements ActionListener, FocusListener {

		FormListener() {
		}

		public void actionPerformed(ActionEvent evt) {
			if (evt.getSource() == btnNewButton) {
				ExperimentPanel.this.btRunXpActionPerformed(evt);
			} else if (evt.getSource() == btnAddTaskToExp) {
				ExperimentPanel.this.addTaskToExp(evt);
			} else if (evt.getSource() == btnRemTaskFromExp) {
				ExperimentPanel.this.remTaskToExp(evt);
			} else if (evt.getSource() == btnAddTry) {
				ExperimentPanel.this.addTry(evt);
			} else if (evt.getSource() == btnRemTry) {
				ExperimentPanel.this.remTry(evt);
			}
		}

		@Override
		public void focusGained(FocusEvent arg0) {
		}

		@Override
		public void focusLost(FocusEvent fcEvt) {
			if (fcEvt.getSource() == textFieldLastname) {
				ExperimentPanel.this.setLastame(fcEvt);
			} else if (fcEvt.getSource() == textFieldName) {
				ExperimentPanel.this.setName(fcEvt);
			} else if (fcEvt.getSource() == textFieldAge) {
				ExperimentPanel.this.setAge(fcEvt);
			} else if (fcEvt.getSource() == textArea) {
				ExperimentPanel.this.setComment(fcEvt);
			} else if (fcEvt.getSource() == nomFichier){
				ExperimentPanel.this.setFile(fcEvt);
			}
		}
	}

	private void btRunXpActionPerformed(ActionEvent evt) {

		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					//On enregistre ici l'xp
					System.out.println(ExperimentRenderer.renderExperiment(experiment));
					ExperimentRenderer.writeFile(ExperimentRenderer.renderExperiment(experiment));
					
					SlideShow slideShow = new SlideShow(experiment.getTrials());
					slideShow.setVisible(true);
					slideShow.play();

				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});

	}

	private void addTaskToExp(ActionEvent evt) {
		if (mainFrame.getTaskList().getSelectedIndex() != -1) {
			taskXpModel.addTask((Task) mainFrame.getTaskList().getSelectedValue());
			nbTryXpModel.setToList(jListTasksExp.getLastVisibleIndex(), 1);
		}
	}

	private void remTaskToExp(ActionEvent evt) {
		nbTryXpModel.removeFromList(jListTasksExp.getSelectedIndex());
		taskXpModel.removeTask(jListTasksExp.getSelectedIndex());
	}

	private void addTry(ActionEvent evt) {
		if (jListTryExp.getSelectedIndex() != -1)
			nbTryXpModel.setToList(jListTryExp.getSelectedIndex(), Integer.parseInt((String) jListTryExp.getSelectedValue().toString()) + 1);
	}

	private void remTry(ActionEvent evt) {
		if (jListTryExp.getSelectedIndex() != -1 && Integer.parseInt((String) jListTryExp.getSelectedValue().toString()) > 0)
			nbTryXpModel.setToList(jListTryExp.getSelectedIndex(), Integer.parseInt((String) jListTryExp.getSelectedValue().toString()) - 1);
	}

	private void setLastame(FocusEvent fcEvt) {
		experiment.setSubjectLastname(textFieldLastname.getText());
	}

	private void setName(FocusEvent fcEvt) {
		experiment.setSubjectName(textFieldName.getText());
	}

	private void setAge(FocusEvent fcEvt) {
		try {
			experiment.setAge(Integer.parseInt(textFieldAge.getText()));
		} catch (NumberFormatException e) {
		}
	}

	private void setComment(FocusEvent fcEvt) {
		experiment.setComment(textArea.getText());
	}
	
	private void setFile(FocusEvent fcEvt){
		try {
			ExperimentRenderer xpRender = new ExperimentRenderer(new PrintWriter(new FileWriter(nomFichier.getText())));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}
